﻿
namespace SistemaLogistica.DataAccess
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Common;
    using SistemaLogistica.Business.Entities;

    public class ClienteData : BaseDataAccess
    {
        private ClienteData() { }

        private readonly static ClienteData instancia = new ClienteData();

        public static ClienteData Instancia
        {
            get { return instancia; }
        }

        public List<Cliente> Listar()
        {
            List<Cliente> coleccion = new List<Cliente>();
            DbCommand cmd = db.GetStoredProcCommand("GetAllFromCliente");
            using (IDataReader dr = db.ExecuteReader(cmd))
            {
                while (dr.Read())
                {
                    Cliente cliente = new Cliente
                    {
                        Direccion = dr.GetString(dr.GetOrdinal("Direccion")),
                        Email = dr.GetString(dr.GetOrdinal("Email")),
                        IdCliente = dr.GetInt32(dr.GetOrdinal("IdCliente")),
                        Telefono = dr.GetString(dr.GetOrdinal("Telefono"))
                    };

                    coleccion.Add(cliente);
                }
            }
            return coleccion;
        }

        public Cliente ObtenerPorID(int IdCliente)
        {
            Cliente cliente = null;
            DbCommand cmd = db.GetStoredProcCommand("GetClienteByIdCliente");
            db.AddInParameter(cmd, "IdCliente", DbType.Int32, IdCliente);
            using (IDataReader dr = db.ExecuteReader(cmd))
            {
                if (dr.Read())
                {
                    cliente = new Cliente
                    {
                        Direccion = dr.GetString(dr.GetOrdinal("Direccion")),
                        Email = dr.GetString(dr.GetOrdinal("Email")),
                        IdCliente = dr.GetInt32(dr.GetOrdinal("IdCliente")),
                        Telefono = dr.GetString(dr.GetOrdinal("Telefono"))
                    };
                }
            }
            return cliente;
        }

        public Juridico ObtenerJuridicoPorID(int IdCliente)
        {
            Juridico juridico = new Juridico();
            DbCommand cmd = db.GetStoredProcCommand("GetJuridicoByIdCliente");
            db.AddInParameter(cmd, "idCliente", DbType.Int32, IdCliente);
            using (IDataReader dr = db.ExecuteReader(cmd))
            {
                if (dr.Read())
                {
                    Cliente cliente = ObtenerPorID(IdCliente);
                    juridico = new Juridico
                    {
                        Email = cliente.Email,
                        Telefono = cliente.Telefono,
                        IdCliente = cliente.IdCliente,
                        Descripcion = cliente.Descripcion,                      
                        RUC = dr.GetString(dr.GetOrdinal("RUC")),
                        RazonSocial = dr.GetString(dr.GetOrdinal("RazonSocial")),
                        GiroNegocio = dr.GetString(dr.GetOrdinal("GiroNegocio")),
                        IdJuridico = dr.GetInt32(dr.GetOrdinal("IdJuridico"))
                    };
                    juridico.Descripcion = juridico.RUC + " / " + juridico.RazonSocial;
                }
            }
            return juridico;
        }

        public Natural ObtenerNaturalPorID(int IdCliente)
        {
            Natural natural = new Natural();
            DbCommand cmd = db.GetStoredProcCommand("GetNaturalByIdCliente");
            db.AddInParameter(cmd, "idCliente", DbType.Int32, IdCliente);
            using (IDataReader dr = db.ExecuteReader(cmd))
            {
                if (dr.Read())
                {
                    Cliente cliente = ObtenerPorID(IdCliente);
                    natural = new Natural
                    {
                        Email = cliente.Email,
                        Telefono = cliente.Telefono,
                        IdCliente = cliente.IdCliente,
                        Descripcion = cliente.Descripcion,
                        DNI = dr.GetString(dr.GetOrdinal("DNI")),
                        Nombre = dr.GetString(dr.GetOrdinal("Nombre")),
                        Apellidos = dr.GetString(dr.GetOrdinal("Apellidos")),
                        IdNatural = dr.GetInt32(dr.GetOrdinal("IdNatural"))
                    };
                    natural.Descripcion = natural.DNI + " / " + natural.Apellidos + " " + natural.Nombre;
                }
            }
            return natural;
        }

        public List<Natural> ListarNaturales()
        {
            List<Natural> coleccion = new List<Natural>();
            DbCommand cmd = db.GetStoredProcCommand("GetAllFromNatural");
            using (IDataReader dr = db.ExecuteReader(cmd))
            {
                while (dr.Read())
                {
                    Cliente cliente = ObtenerPorID(dr.GetInt32(dr.GetOrdinal("IdCliente")));
                    Natural natural = new Natural
                    {
                        Email = cliente.Email,
                        Telefono = cliente.Telefono,
                        IdCliente = cliente.IdCliente,
                        Descripcion = cliente.Descripcion,
                        DNI = dr.GetString(dr.GetOrdinal("DNI")),
                        Nombre = dr.GetString(dr.GetOrdinal("Nombre")),
                        Apellidos = dr.GetString(dr.GetOrdinal("Apellidos")),
                        IdNatural = dr.GetInt32(dr.GetOrdinal("IdNatural"))
                    };
                    natural.Descripcion = natural.DNI + " / " + natural.Apellidos + " " + natural.Nombre;
                    coleccion.Add(natural);
                }
            }
            return coleccion;
        }

        public List<Natural> BuscarNatural(string DNI)
        {
            List<Natural> coleccion = new List<Natural>();
            DbCommand cmd = db.GetStoredProcCommand("GetNaturalByDNI");
            db.AddInParameter(cmd, "DNI", DbType.String, DNI);
            using (IDataReader dr = db.ExecuteReader(cmd))
            {
                while (dr.Read())
                {
                    Cliente cliente = ObtenerPorID(dr.GetInt32(dr.GetOrdinal("IdCliente")));
                    Natural natural = new Natural
                    {
                        Email = cliente.Email,
                        Telefono = cliente.Telefono,
                        IdCliente = cliente.IdCliente,
                        Descripcion = cliente.Descripcion,
                        DNI = dr.GetString(dr.GetOrdinal("DNI")),
                        Nombre = dr.GetString(dr.GetOrdinal("Nombre")),
                        Apellidos = dr.GetString(dr.GetOrdinal("Apellidos")),
                        IdNatural = dr.GetInt32(dr.GetOrdinal("IdNatural"))
                    };
                    natural.Descripcion = natural.DNI + " / " + natural.Apellidos + " " + natural.Nombre;
                    coleccion.Add(natural);
                }
            }
            return coleccion;
        }

        public List<Juridico> ListarJuridicos()
        {
            List<Juridico> coleccion = new List<Juridico>();
            DbCommand cmd = db.GetStoredProcCommand("GetAllFromJuridico");
            using (IDataReader dr = db.ExecuteReader(cmd))
            {
                while (dr.Read())
                {
                    Cliente cliente = ObtenerPorID(dr.GetInt32(dr.GetOrdinal("IdCliente")));
                    Juridico juridico = new Juridico
                    {
                        Email = cliente.Email,
                        Telefono = cliente.Telefono,
                        IdCliente = cliente.IdCliente,
                        Descripcion = cliente.Descripcion,                      
                        RUC = dr.GetString(dr.GetOrdinal("RUC")),
                        RazonSocial = dr.GetString(dr.GetOrdinal("RazonSocial")),
                        GiroNegocio = dr.GetString(dr.GetOrdinal("GiroNegocio")),
                        IdJuridico = dr.GetInt32(dr.GetOrdinal("IdJuridico"))
                    };
                    juridico.Descripcion = juridico.RUC + " / " + juridico.RazonSocial;
                    coleccion.Add(juridico);
                }
            }
            return coleccion;
        }

        public List<Juridico> BuscarJuridico(string RUC)
        {
            List<Juridico> coleccion = new List<Juridico>();
            DbCommand cmd = db.GetStoredProcCommand("GetJuridicoByRUC");
            db.AddInParameter(cmd, "RUC", DbType.String, RUC);
            using (IDataReader dr = db.ExecuteReader(cmd))
            {
                while (dr.Read())
                {
                    Cliente cliente = ObtenerPorID(dr.GetInt32(dr.GetOrdinal("IdCliente")));
                    Juridico juridico = new Juridico
                    {
                        Email = cliente.Email,
                        Telefono = cliente.Telefono,
                        IdCliente = cliente.IdCliente,
                        Descripcion = cliente.Descripcion,
                        RUC = dr.GetString(dr.GetOrdinal("RUC")),
                        RazonSocial = dr.GetString(dr.GetOrdinal("RazonSocial")),
                        GiroNegocio = dr.GetString(dr.GetOrdinal("GiroNegocio")),
                        IdJuridico = dr.GetInt32(dr.GetOrdinal("IdJuridico"))
                    };
                    juridico.Descripcion = juridico.RUC + " / " + juridico.RazonSocial;
                    coleccion.Add(juridico);
                }
            }
            return coleccion;
        }

        public bool AgregarNatural(Natural natural)
        {
            using (DbConnection cnn = db.CreateConnection())
            {
                cnn.Open();
                using (DbTransaction tran = cnn.BeginTransaction())
                {
                    try
                    {
                        DbCommand cmdC = db.GetStoredProcCommand("InsertCliente");
                        db.AddInParameter(cmdC, "direccion", DbType.String, natural.Direccion);
                        db.AddInParameter(cmdC, "email", DbType.String, natural.Email);
                        db.AddOutParameter(cmdC, "idCliente", DbType.Int32, 11);
                        db.AddInParameter(cmdC, "telefono", DbType.String, natural.Telefono);

                        int huboexito = db.ExecuteNonQuery(cmdC, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }

                        int idCliente = int.Parse(db.GetParameterValue(cmdC, "idCliente").ToString());

                        DbCommand cmdN = db.GetStoredProcCommand("InsertNatural");
                        db.AddInParameter(cmdN, "apellidos", DbType.String, natural.Apellidos);
                        db.AddInParameter(cmdN, "dNI", DbType.String, natural.DNI);
                        db.AddInParameter(cmdN, "idCliente", DbType.Int32, idCliente);
                        db.AddOutParameter(cmdN, "idNatural", DbType.Int32, 11);
                        db.AddInParameter(cmdN, "nombre", DbType.String, natural.Nombre);
                        huboexito = db.ExecuteNonQuery(cmdN, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }
                        tran.Commit();
                    }
                    catch (Exception ex)
                    {
                        tran.Rollback();
                        throw new Exception(ex.Message);
                    }
                }
            }
            return true;
        }

        public bool AgregarJuridico(Juridico juridico)
        {
            using (DbConnection cnn = db.CreateConnection())
            {
                cnn.Open();
                using (DbTransaction tran = cnn.BeginTransaction())
                {
                    try
                    {
                        DbCommand cmdC = db.GetStoredProcCommand("InsertCliente");
                        db.AddInParameter(cmdC, "direccion", DbType.String, juridico.Direccion);
                        db.AddInParameter(cmdC, "email", DbType.String, juridico.Email);
                        db.AddOutParameter(cmdC, "idCliente", DbType.Int32, 11);
                        db.AddInParameter(cmdC, "telefono", DbType.String, juridico.Telefono);

                        int huboexito = db.ExecuteNonQuery(cmdC, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }

                        int idCliente = int.Parse(db.GetParameterValue(cmdC, "idCliente").ToString());

                        DbCommand cmdJ = db.GetStoredProcCommand("InsertJuridico");
                        db.AddInParameter(cmdJ, "giroNegocio", DbType.String, juridico.GiroNegocio);
                        db.AddInParameter(cmdJ, "rUC", DbType.String, juridico.RUC);
                        db.AddInParameter(cmdJ, "idCliente", DbType.Int32, idCliente);
                        db.AddOutParameter(cmdJ, "idJuridico", DbType.Int32, 11);
                        db.AddInParameter(cmdJ, "razonSocial", DbType.String, juridico.RazonSocial);
                        huboexito = db.ExecuteNonQuery(cmdJ, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }
                        tran.Commit();
                    }
                    catch (Exception ex)
                    {
                        tran.Rollback();
                        throw new Exception(ex.Message);
                    }
                }
            }
            return true;
        }

        public bool EditarNatural(Natural natural)
        {
            using (DbConnection cnn = db.CreateConnection())
            {
                cnn.Open();
                using (DbTransaction tran = cnn.BeginTransaction())
                {
                    try
                    {
                        DbCommand cmdC = db.GetStoredProcCommand("UpdateCliente");
                        db.AddInParameter(cmdC, "direccion", DbType.String, natural.Direccion);
                        db.AddInParameter(cmdC, "email", DbType.String, natural.Email);
                        db.AddInParameter(cmdC, "idCliente", DbType.Int32, natural.IdCliente);
                        db.AddInParameter(cmdC, "telefono", DbType.String, natural.Telefono);

                        int huboexito = db.ExecuteNonQuery(cmdC, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }

                        DbCommand cmdN = db.GetStoredProcCommand("UpdateNatural");
                        db.AddInParameter(cmdN, "apellidos", DbType.String, natural.Apellidos);
                        db.AddInParameter(cmdN, "dNI", DbType.String, natural.DNI);
                        db.AddInParameter(cmdN, "idCliente", DbType.Int32, natural.IdCliente);
                        db.AddInParameter(cmdN, "idNatural", DbType.Int32, natural.IdNatural);
                        db.AddInParameter(cmdN, "nombre", DbType.String, natural.Nombre);
                        huboexito = db.ExecuteNonQuery(cmdN, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }
                        tran.Commit();
                    }
                    catch (Exception ex)
                    {
                        tran.Rollback();
                        throw new Exception(ex.Message);
                    }
                }
            }
            return true;
        }

        public bool EditarJuridico(Juridico juridico)
        {
            using (DbConnection cnn = db.CreateConnection())
            {
                cnn.Open();
                using (DbTransaction tran = cnn.BeginTransaction())
                {
                    try
                    {
                        DbCommand cmdC = db.GetStoredProcCommand("UpdateCliente");
                        db.AddInParameter(cmdC, "direccion", DbType.String, juridico.Direccion);
                        db.AddInParameter(cmdC, "email", DbType.String, juridico.Email);
                        db.AddInParameter(cmdC, "idCliente", DbType.Int32, juridico.IdCliente);
                        db.AddInParameter(cmdC, "telefono", DbType.String, juridico.Telefono);

                        int huboexito = db.ExecuteNonQuery(cmdC, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }

                        DbCommand cmdJ = db.GetStoredProcCommand("UpdateJuridico");
                        db.AddInParameter(cmdJ, "giroNegocio", DbType.String, juridico.GiroNegocio);
                        db.AddInParameter(cmdJ, "rUC", DbType.String, juridico.RUC);
                        db.AddInParameter(cmdJ, "idCliente", DbType.Int32, juridico.IdCliente);
                        db.AddInParameter(cmdJ, "idJuridico", DbType.Int32, juridico.IdJuridico);
                        db.AddInParameter(cmdJ, "razonSocial", DbType.String, juridico.RazonSocial);
                        huboexito = db.ExecuteNonQuery(cmdJ, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }
                        tran.Commit();
                    }
                    catch (Exception ex)
                    {
                        tran.Rollback();
                        throw new Exception(ex.Message);
                    }
                }
            }
            return true;
        }

        public bool Eliminar(int idCliente)
        {
            using (DbConnection cnn = db.CreateConnection())
            {
                cnn.Open();
                using (DbTransaction tran = cnn.BeginTransaction())
                {
                    try
                    {
                        int huboexito;
                        Cliente Cli = this.ObtenerPorID(idCliente);
                        if (Cli != null)
                        {
                            DbCommand cmdN = db.GetStoredProcCommand("DeleteNatural");
                            db.AddInParameter(cmdN, "idCliente", DbType.Int32, idCliente);
                            huboexito = db.ExecuteNonQuery(cmdN, tran);
                            if (huboexito == 0)
                            {
                                throw new Exception("Error");
                            }
                        }
                        else
                        {
                            DbCommand cmdJ = db.GetStoredProcCommand("DeleteJuridico");
                            db.AddInParameter(cmdJ, "idCliente", DbType.Int32, idCliente);
                            huboexito = db.ExecuteNonQuery(cmdJ, tran);
                            if (huboexito == 0)
                            {
                                throw new Exception("Error");
                            }
                        }

                        DbCommand cmdC = db.GetStoredProcCommand("DeleteCliente");
                        db.AddInParameter(cmdC, "idCliente", DbType.Int32, idCliente);
                        huboexito = db.ExecuteNonQuery(cmdC, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }
                        tran.Commit();
                    }
                    catch (Exception ex)
                    {
                        tran.Rollback();
                        throw new Exception(ex.Message);
                    }
                }
            }
            return true;
        }
    }
}
